package com.sf.ams.logging;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

/**
 * 描述：
 * 
 * <pre>HISTORY
 * ****************************************************************************
 *  ID   DATE           PERSON          REASON
 *  1    2017年11月3日      Simba.Hua         Create
 * ****************************************************************************
 * </pre>
 * @author Simba.Hua
 */
@Component
@Aspect
public class CommonLoggingAdvice implements Ordered {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Pointcut(value = "@annotation(com.sf.ams.logging.CommonLogging)")
	private void pointCut() {
	}
	@Around(value = "pointCut() && @annotation(logging)")
	public Object otherAround(ProceedingJoinPoint joinPoint,CommonLogging logging) {
		MethodSignature signature = (MethodSignature)joinPoint.getSignature();
		Method method = signature.getMethod();
		String className = method.getDeclaringClass().getName();
		long startTime = System.currentTimeMillis();
		
		before(className,method,joinPoint,logging);
		Object result = null;
		result = executeMethod( joinPoint, method.getName());
		after(className,method,logging, startTime);
		return result;
	}
	public Object executeMethod(ProceedingJoinPoint joinPoint,String methodName) {
		try {
			return joinPoint.proceed();
		} catch (Throwable e) {
			logger.error("execute method {} error",methodName,e);
		}
		return null;
	}
	private void before(String className,Method method,ProceedingJoinPoint joinPoint,CommonLogging logging){
		logger.info("{}.{} 开始{}，参数为：",className,method.getName(),logging.content());
		List<Object> param = Arrays.asList(joinPoint.getArgs());
		param.forEach(p -> logger.info(p.toString()));
	}
	
	private void after(String className,Method method,CommonLogging logging,long startTime) {
		long endTime = System.currentTimeMillis();
		logger.info("{}.{} 结束{}，共耗时{} ms",className,method.getName(),logging.content(),endTime - startTime);
	}
	@Override
	public int getOrder() {
		return 100;
	}

}
